/**
 * GisController - part of PerlaGis Architecture
 *
 * Copyright (C) 2010 Ricardo Gonzalez (gomnaz@gmail.com)
 * This program is free software: you can redistribute it and/or modify it under the
 * terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later version.
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
 * Public License for more details.
 * You should have received a copy of the GNU General Public License along with
 * this program. If not, see http://www.gnu.org/licenses/
 */
package org.gis.services;

import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.Resource;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.gis.controllers.Perla;
import org.gis.controllers.Sensor;
import org.gis.entities.Sensori;
import org.gis.exceptions.NoSuchSensorException;
import org.perla.services.Attitude;
import org.perla.services.Bibi;
import org.perla.services.NoSuchSensorException_Exception;
import org.perla.services.Temperature;
import org.perla.services.WrongSensorTypeException_Exception;

/**
 * Classe che rappresenta i servizi operativi del GisController.
 * Implementa i metodi necessari a ricevere e richiedere i nuovi valori dei
 * sensori.
 *
 * @author Ricardo Gonzalez
 * @author Eva Gjeci
 */
@WebService()
public class Operative {

    @Resource
    private javax.transaction.UserTransaction utx;
    @PersistenceContext(unitName = "GisController")
    private EntityManager em;

    /**
     * Effettua la richiesta degli ultimi valori per il sensore corrispondente
     * alla chiave passata come parametro.
     *
     * @param idSensore la chiave del sensorei
     * @throws NoSuchSensorException se la chiave non corrisponde ad alcun sensore
     */
    @WebMethod(operationName = "requestUpdate")
    public void requestUpdate(@WebParam(name = "idSensore") int idSensore) throws NoSuchSensorException {
        Sensori s = Sensor.get(idSensore, em);
        try {
            Attitude a = Perla.getLastAttitudeValue("" + idSensore);
            Temperature t = Perla.getLastTemperatureValue("" + idSensore);
            Bibi b = Perla.getLastBibiValue("" + idSensore);
            s.setGeofoni((float) b.getMagnitudez());
            s.setTemperatura((short) t.getValue().floatValue());
            s.setAccelerometro((float) a.getAttitudeX());
            saveSensor(s);
        } catch (WrongSensorTypeException_Exception ex) {
            Logger.getLogger(Operative.class.getName()).log(Level.SEVERE, null, ex);
        } catch (NoSuchSensorException_Exception ex) {
            Logger.getLogger(Operative.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    /**
     * Riceve i nuovi valori per il sensore corrispondente alla chiave passata
     * per parametro.
     * I valori vengono inseriti nel database in sostituzione di quelli vecchi.
     *
     * @param idSensore la chiave del sensore
     * @param accelerometro il valore dell'accelerometro
     * @param geofoni il valore dei geofoni
     * @param temperatura il valore della temperatura
     * @throws NoSuchSensorException se non esiste un sensore relativo alla chiave passata
     */
    @WebMethod(operationName = "receiveUpdate")
    public void receiveUpdate(@WebParam(name = "idSensore") int idSensore, @WebParam(name = "attitude") float accelerometro, @WebParam(name = "bibi") float geofoni, @WebParam(name = "temperature") short temperatura) throws NoSuchSensorException {
        Sensori s = Sensor.get(idSensore, em);
        s.setGeofoni(geofoni);
        s.setTemperatura(temperatura);
        s.setAccelerometro(accelerometro);
        saveSensor(s);
    }

    /**
     * Salva le modifiche al sensore.
     *
     * @param object l'oggetto sensore
     * @return true se la modifica ha avuto successo
     */
    protected boolean saveSensor(Object object) {
        boolean result = true;
        try {
            utx.begin();
            em.joinTransaction();
            em.merge(object);
            utx.commit();
        } catch (Exception e) {
            Logger.getLogger(getClass().getName()).log(Level.SEVERE, "exception caught", e);
            result = false;
            throw new RuntimeException(e);
        } finally {
            return result;
        }
    }
}
